package com.vic.commons.utils;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URI;
import java.net.URISyntaxException;
import java.security.KeyManagementException;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;

import org.apache.commons.io.IOUtils;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpDelete;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpRequestBase;
import org.apache.http.config.Registry;
import org.apache.http.config.RegistryBuilder;
import org.apache.http.conn.socket.ConnectionSocketFactory;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.conn.ssl.TrustStrategy;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.ssl.SSLContexts;
import org.apache.http.util.EntityUtils;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.vic.commons.Constants;


public class HttpsUtils {
	
	public static Object getDate(JSONObject responseDate) throws Exception{
		if(responseDate.getString(Constants.RESPONSE_CODE) .equals(Constants.RESPONSE_STATUS_SUCCESS))
			return responseDate.containsKey(Constants.RESPONSE_DATA)?responseDate.get(Constants.RESPONSE_DATA):null;
		throw new Exception("service execute error");
	}
	/**
	   * 
	   * @param url
	   * @param contextType  "image/jpeg","application/Json"
	   * @return
	 * @throws IOException 
	 * @throws CertificateException 
	 * @throws KeyStoreException 
	 * @throws NoSuchAlgorithmException 
	 * @throws KeyManagementException 
	   */
	public static CloseableHttpClient createSSLClientDefault() throws CertificateException, IOException, KeyStoreException, KeyManagementException, NoSuchAlgorithmException{
		org.apache.http.ssl.SSLContextBuilder builder = SSLContexts.custom();
		builder.loadTrustMaterial(null, new TrustStrategy() {
		    @Override
		    public boolean isTrusted(X509Certificate[] chain, String authType)
		            throws CertificateException {
		        return true;
		    }
		});
		SSLContext sslContext = builder.build();
		SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(
		        sslContext, new javax.net.ssl.HostnameVerifier() {
		            @Override
		            public boolean verify(String s, SSLSession sslSession) {
		                return true;
		            }
		        });

		Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder
		        .<ConnectionSocketFactory> create().register("https", sslsf)
		        .build();

		PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager(
		        socketFactoryRegistry);
		return HttpClients.custom()
		        .setConnectionManager(cm).build();
		}
	
	public static JSONObject doGet(String url,Map<String,String>header,String charset) throws IOException{
		CloseableHttpClient httpClient = null;
		try {
			httpClient = createSSLClientDefault();
			HttpGet get = new HttpGet();
			constructHeader(get, header);
			get.setURI(new URI(url));
			HttpResponse response = httpClient.execute( get); 
		    return response2jsonObject(charset, response);
		} catch (CertificateException | IOException | URISyntaxException | KeyStoreException | KeyManagementException | NoSuchAlgorithmException e) {
			e.printStackTrace();
		}finally{
			httpClient.close();
		}
		return null;
	}
	
	private static JSONObject response2jsonObject(String charset, HttpResponse response)
			throws IOException, UnsupportedEncodingException {
		HttpEntity entity = response.getEntity();
		JSONObject jo = JSON.parseObject(new String(IOUtils.toByteArray(entity.getContent()), charset));
		if (null != entity) {
			EntityUtils.consume(entity); // Consume response content
		}
		return jo;
	}
	public static JSONObject doGet(String url) throws IOException{
		return doGet(url, constructDefaultHeader());
	}
	public static JSONObject doGet(String url,Map<String,String>header) throws IOException{
		return doGet(url, header,"utf-8");
	}
	
	public static JSONObject doPost(String url,Map<String, Object> params,Map<String,String>header) throws IOException{
		return doPost(url,params,header,"utf-8");
	}
	
	public static JSONObject doPost(String url,Map<String, Object> params) throws IOException{
		return doPost(url,params,constructDefaultHeader());
	}
	public static JSONObject doDelete(String url,Map<String,String>header) throws IOException{
		return doDelete(url,header,"utf-8");
	}
	public static JSONObject doDelete(String url) throws IOException{
		return doDelete(url,constructDefaultHeader());
	}
	public static JSONObject doPost(String url,Map<String, Object> params,Map<String,String>header,String charset) throws IOException{
		CloseableHttpClient httpClient = null;
		try {
			httpClient = createSSLClientDefault();
			HttpPost post = postForm(url, params);
			constructHeader(post, header);
			HttpResponse response = httpClient.execute(post); 
			return response2jsonObject(charset, response);
		} catch (CertificateException | IOException | KeyStoreException | KeyManagementException | NoSuchAlgorithmException e) {
			e.printStackTrace();
		}finally{
			httpClient.close();
		}
		return null;
	}
	
	public static JSONObject doDelete(String url,Map<String,String>header,String charset) throws IOException{
		CloseableHttpClient httpClient = null;
		try {
			httpClient = createSSLClientDefault();
			HttpDelete delete = new HttpDelete();
			delete.setURI(new URI(url));
			HttpResponse response = httpClient.execute( delete); 
		    return response2jsonObject(charset, response);
		} catch (CertificateException | IOException | URISyntaxException | KeyStoreException | KeyManagementException | NoSuchAlgorithmException e) {
			e.printStackTrace();
		}finally{
			httpClient.close();
		}
		return null;
	}
	
	private static Map<String,String> constructDefaultHeader(){
		Map<String,String> map = new HashMap<String, String>();
		map.put("v1", "2e567596b97b0409b5f58457a47d5584");
		return map;
	}
	
	private static void constructHeader(HttpRequestBase reques,Map<String,String> headers){
		if(headers == null || headers.isEmpty())
			return ;
		Set<String> keySet = headers.keySet();
		for(String key : keySet){
			reques.addHeader(key, headers.get(key));
		}
	}
	
	
	private static HttpPost postForm(String url, Map<String, Object> params){  
        
        HttpPost httpost = new HttpPost(url);  
        List<NameValuePair> nvps = new ArrayList <NameValuePair>();  
        Set<String> keySet = params.keySet();  
        for(String key : keySet) {  
        	if(params.get(key) != null)
        		nvps.add(new BasicNameValuePair(key, String.valueOf(params.get(key))));  
        }  
        try {  
            httpost.setEntity(new UrlEncodedFormEntity(nvps,"utf-8"));  
        } catch (UnsupportedEncodingException e) {  
            e.printStackTrace();  
        }  
          
        return httpost;  
    }  
}
